package com.beeweeb.services.tps.mbean;

import com.beeweeb.services.tps.text.DefaultSimpleDateFormat;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import org.jboss.system.ServiceMBeanSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * In this class all methods and fields which
 * @author Guido D'Albore
 */

public abstract class ThreadPoolSchedulerSupport extends ServiceMBeanSupport {
    Logger logger = LoggerFactory.getLogger("ThreadPoolScheduler");

    private static final int MAX_THREAD_COUNT       = 1000;

    DefaultSimpleDateFormat sdf = new DefaultSimpleDateFormat();

    String lastError;

    boolean startQuartzAtStartup;
    Date startDate;
    Date endDate;
    int repeatCount;
    long repeatInterval;
    int threadPoolSize;
    int jobPoolAcceptedCount;
    String jobPoolExecutorClass;
    String jobInstanceName;
    boolean jobPoolExclusiveExecution;
    boolean useCronTrigger;
    boolean inUserTransaction;

    public ThreadPoolSchedulerSupport() {
        // Scheduling parameters
        startQuartzAtStartup  = false;
        startDate       = null;
        endDate         = null;
        repeatCount     = -1;
        repeatInterval  = -1L;

        // Thread pooling parameters
        threadPoolSize  = 10;    // default
        jobPoolAcceptedCount = Integer.MAX_VALUE;
    }

    public abstract void configurationUpdated();
    
    @Override
    protected void startService() throws Exception {
        super.startService();

    }

    @Override
    protected void stopService() throws Exception {
        super.stopService();
    }

    public int getThreadPoolSize() {
        return threadPoolSize;
    }

    public void setThreadPoolSize(int threadPoolSize) {
        threadPoolSize = Math.max(threadPoolSize, 1);
        threadPoolSize = Math.min(threadPoolSize, MAX_THREAD_COUNT);

        if(threadPoolSize != this.threadPoolSize) {
            this.threadPoolSize = threadPoolSize;
            //configurationUpdated();
        }
    }

    public String getStartDate() {
        if(startDate != null) {
            return sdf.format(startDate);
        } else {
            return "*";
        }
    }
    public void setStartDate(String startDate) {
        try {
            if((startDate != null) && !startDate.equals("*")) {
                Date newValue = sdf.parse(startDate);

                if((this.startDate == null) || (newValue.compareTo(this.startDate) != 0)) {
                    this.startDate = newValue;
                    //configurationUpdated();
                }
            } else {
                if(this.startDate != null) {
                    this.startDate = null;
                    //configurationUpdated();
                }
            }
        } catch(Exception ex) {
            logger.error("Cannot set 'startDate' parameter. The parameter won't change.", ex);
        }
    }
    
    public String getEndDate() {
        if(endDate != null) {
            return sdf.format(endDate);
        } else {
            return "*";
        }
    }

    public void setEndDate(String endDate) {
        try {
            if((endDate != null) && !endDate.equals("*")) {
                Date newValue = sdf.parse(endDate);

                if((this.endDate == null) || newValue.compareTo(this.endDate) != 0) {
                    this.endDate = newValue;
                    //configurationUpdated();
                }
            } else {
                if(this.endDate != null) {
                    this.endDate = null;
                    //configurationUpdated();
                }
            }
        } catch(Exception ex) {
            logger.error("Cannot set 'endDate' parameter. The parameter won't change.", ex);
        }
    }

    public String getRepeatCount() {
        if(repeatCount != -1) {
            return String.valueOf(repeatCount);
        } else {
            return "*";
        }
    }

    public void setRepeatCount(String repeatCount) {
        try {
            if((repeatCount != null) && !repeatCount.equals("*")) {
                int newValue = Integer.parseInt(repeatCount);

                if(newValue >= 0) {
                    if(newValue != this.repeatCount) {
                        this.repeatCount = newValue;
                        //configurationUpdated();
                    }
                }
            } else {
                if(this.repeatCount != -1) {
                    this.repeatCount = -1;
                    //configurationUpdated();
                }
            }
        } catch(Exception ex) {
            logger.error("Cannot set 'repeatCount' parameter. This parameter will be set to default '*'.", ex);
        }
    }

    public String getRepeatIntervalInMs() {
        if(repeatInterval != -1) {
            return String.valueOf(repeatInterval);
        } else {
            return "*";
        }
    }

    public void setRepeatIntervalInMs(String repeatInterval) {
        try {
            if((repeatInterval != null) && !repeatInterval.equals("*")) {
                long newValue = Long.parseLong(repeatInterval);

                if(newValue >= 0) {
                    if(newValue != this.repeatInterval) {
                        this.repeatInterval = newValue;
                        //configurationUpdated();
                    }
                }
            } else {
                if(this.repeatInterval != -1L) {
                    this.repeatInterval = -1L;
                    //configurationUpdated();
                }
            }
        } catch(Exception ex) {
            logger.error("Cannot set 'repeatInterval' parameter. This parameter will be set to default '*'.", ex);
        }
    }

    public boolean getStartQuartzAtStartup() {
        return startQuartzAtStartup;
    }

    public void setStartQuartzAtStartup(boolean startAtStartup) {
        this.startQuartzAtStartup = startAtStartup;
    }

//    public String getSchedulerStatus() {
//        switch(getState()) {
//            case ServiceMBean.STARTED:  return "RUNNING";
//            default:                    return "NOT RUNNING";
//        }
//    }

    public String displayLastError() {
        if((lastError == null) || (lastError.length() == 0)) {
            return "No error found.";
        }

        return lastError;
    }
    
    public String getLastError() {
        if((lastError == null) || (lastError.length() == 0)) {
            return "No error found.";
        }
        
        return "Error found.";
    }

    public void setLastError(String lastError) {
        this.lastError = lastError;
    }

    public String getStackTrace(Exception ex) {
        StringWriter    sw = new StringWriter();
        PrintWriter     pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        return sw.getBuffer().toString();
    }

    public String getNextTriggeringDate() {
        return "";
    }

    public String getJobPoolExecutorClass() {
        return jobPoolExecutorClass;
    }

    public void setJobPoolExecutorClass(String JobExecutorClass) {
        this.jobPoolExecutorClass = JobExecutorClass;
    }

    public String getJobInstanceName() {
        return jobInstanceName;
    }

    public void setJobInstanceName(String jobInstanceName) {
        this.jobInstanceName = jobInstanceName;
    }

    

    public String getJobPoolAcceptedCount() {
        if(this.jobPoolAcceptedCount == Integer.MAX_VALUE) {
            return "*";
        }

        return String.valueOf(jobPoolAcceptedCount);
    }
    
    public void setJobPoolAcceptedCount(String jobPoolAcceptedCount) {
        try {
            if((jobPoolAcceptedCount != null) && !jobPoolAcceptedCount.equals("*")) {
                int newValue = Integer.parseInt(jobPoolAcceptedCount);

                if(newValue > 0) {
                    if(newValue != this.jobPoolAcceptedCount) {
                        this.jobPoolAcceptedCount = newValue;
                        //configurationUpdated();
                    }
                }
            } else {
                if(this.jobPoolAcceptedCount != Integer.MAX_VALUE) {
                    this.jobPoolAcceptedCount = Integer.MAX_VALUE;
                    //configurationUpdated();
                }
            }
        } catch(Exception ex) {
            logger.error("Cannot set 'jobPoolAcceptedCount' parameter. This parameter will be set to default '*'.", ex);
        }
    }

    public boolean getJobPoolExclusiveExecution() {
        return jobPoolExclusiveExecution;
    }
    
    public void setJobPoolExclusiveExecution(boolean flag) {
        jobPoolExclusiveExecution = flag;
    }

    public void setUseCronTrigger(boolean useCronTrigger) {
        this.useCronTrigger = useCronTrigger;
    }

    public boolean getUseCronTrigger() {
        return useCronTrigger;
    }

    public boolean isInUserTransaction() {
        return inUserTransaction;
    }

    public void setInUserTransaction(boolean inUserTransaction) {
        this.inUserTransaction = inUserTransaction;
    }
    
    
}
